using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;

namespace FreeFlow.Administration.WinFormsControls
{
  internal static class NativeMethods
  {
    internal const Int64 SQL_SUCCESS = 0;    // ODBC sucess 
    internal const Int64 SQL_ERROR = -1;     // ODBC error 
    internal const Int32 SQL_FETCH_NEXT = 1; // ODBC Move Next 

    /// <summary> 
    /// ODBC WinAPI functions to retrieve the DSNs. 
    /// </summary> 
    [DllImport("ODBC32.DLL", EntryPoint = "SQLDataSources",
       SetLastError = true,
       CharSet = CharSet.Ansi, ExactSpelling = true,
       CallingConvention = CallingConvention.StdCall)]
    internal static extern short SQLDataSources(IntPtr EnvironmentHandle,
      Int16 Direction,
      StringBuilder ServerName,
      Int16 BufferLength1, ref Int16 NameLength1Ptr, 
      StringBuilder Description,
      Int16 BufferLength2, ref Int16 NameLength2Ptr);

    [DllImport("ODBC32.DLL", EntryPoint = "SQLAllocEnv",
       SetLastError = true,
       CharSet = CharSet.Ansi, ExactSpelling = true,
       CallingConvention = CallingConvention.StdCall)]
    internal static extern Int32 SQLAllocEnv(ref IntPtr env);

    [DllImport("ODBC32.DLL", EntryPoint = "SQLFreeEnv", SetLastError = true,
       CharSet = CharSet.Ansi, ExactSpelling = true,
       CallingConvention = CallingConvention.StdCall)]
    internal static extern Int32 SQLFreeEnv(IntPtr hEnv); 
  }

  /// <summary> 
  /// DSN class, that contains all DSN installed on the system. 
  /// </summary> 
  public static class DSN 
  { 
    private static Hashtable _DSNs = new Hashtable(); 

    static DSN()
    {
      GetDSNs();
    }

    /// <summary> 
    /// Gets all DSN installed on the system. 
    /// </summary> 
    private static void GetDSNs() 
    { 
      Int16 RetCode, DSNLen = 0, DrvLen = 0; 
      StringBuilder DSNItem, DRVItem; 
      String DSN; 
      IntPtr hEnv = IntPtr.Zero; 

      _DSNs.Clear();

      if (NativeMethods.SQLAllocEnv(ref hEnv) != NativeMethods.SQL_ERROR) 
      { 
        do 
        { 
          DSNItem = new StringBuilder(1024); 
          DRVItem = new StringBuilder(1024);

          RetCode = NativeMethods.SQLDataSources(hEnv, NativeMethods.SQL_FETCH_NEXT, DSNItem, 1024, 
            ref DSNLen, DRVItem, 1024, ref DrvLen);
          if (RetCode == NativeMethods.SQL_SUCCESS)
          {
            if (DSNItem != null) 
            { 
              DSNItem.Length = DSNLen; 
              DSN = DSNItem.ToString(); 
              DRVItem.Length = DrvLen; 
              _DSNs.Add(DSN, DSN + " (" + DRVItem + ")");  
            }
          }
        }
        while (RetCode == NativeMethods.SQL_SUCCESS);
        NativeMethods.SQLFreeEnv(hEnv); 
      } 
    } 


    /// <summary> 
    /// Gets all DSNs connected with this object. 
    /// </summary> 
    public static Hashtable DSNs 
    { 
      get { return _DSNs; } 
    } 
  }
}
